/*
TODO：promise:
三种状态：pending、resolved、rejected
一旦创建promise就会立马执行(创建属于同步任务),(.then/.catch属于微任务)
可以有多个.then 与.finally,会按顺序依次执行,多个.catch只会执行一次（除非在.catch中会抛出异常throw）
在多个.then中想要跳出.then可以在.then中抛出异常，一旦有异常就直接执行.catch,不在执行后续的.then
无论是成功状态还是失败状态都会执行.finally
promise的状态只能改变一次
.then()可以接收两个回调函数作为参数，第一个是resolve成功触发，第二个是reject失败触发
.catch只会捕获最近的.then回调错误的结果
*/
//00000 11111 22222 err33333:err0 undefined:success abc:err
// 00000 11111 err undefined:success abc:error
const promise = new Promise((resolve, reject) => {
    console.log('00000')
    // resolve('22222')
    reject('err')
})
promise.then((success) => {
    //成功
    console.log(success)
    throw 'err33333'
    // return success
}, (err) => {
    //失败
    console.log(err)
}).catch(err => {
    console.log(err, ':err0')
})
    .then((success) => {
        console.log(success, ':success')
        throw 'abc'
    }, (err) => {
        console.log(err)
    }).catch(err => {
        console.log(err, ':err')
    })
console.log('11111')

//resolve('22222')执行结果：00000   11111  22222  err33333:err0  undefined:success  abc:err
//reject('err')执行结果：00000   11111 err undefined abc

const p = new Promise(function (resolve, reject) {
    resolve(1);
}).then(function (value) { // 第一个then // 1
    console.log(value);
    return value * 2;
}).then(function (value) { // 第二个then // 2
    console.log(value);
}).then(function (value) { // 第三个then // undefined
    console.log(value);
    return Promise.resolve('resolve');
}).then(function (value) { // 第四个then // resolve
    console.log(value);
    return Promise.reject('reject');
}).then(function (value) {
    console.log('resolve:' + value);
}, function (err) {   // 第五个then //reject:reject
    console.log('reject:' + err);
});


/**
 * 与 Promise.all 不同，
 * Promise.allSettled 不会因单个失败而中断，而是等待所有 Promise 完成
*/
/**
 * promise.all()
 * 参数是一个数组，数组中的每个元素都是一个promise实例，promise.all只不过是把多个promise实例汇总成一个新的promise实例
 * 数组中的元素所有promise实例是成功状态，promise.all()才是成功状态，任意一个是失败状态，promise.all()就是失败状态
 * 如果promise.all()参数是一个空数组，promise.all()的状态直接就是成功状态
*/

const p1 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第一条数据')
            resolve('1')
        }, 3000)
    })
}
const p2 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第二条数据')
            resolve('2')
        }, 2000)
    })
}
const p3 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第三条数据')
            resolve('3')
        }, 1000)
    })
}

const p4 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('4')
        }, 10000)
    })
}
const p5 = () => {
    return new Promise((resolve, reject) => {
        reject('5')
    })
}
const pAll = Promise.all([p1(), p2(), p3()])
const pAll1 = Promise.all([])
/**
 * 返回结果会按照数组中的元素排列一一对应
*/
pAll.then((res) => {
    console.log(res, 'res')   // [1,2,3]
}).catch((err) => {
    console.log(err, 'err')
})
pAll1.then(res => {
    console.log(res, 'res--pall1')
}).catch((err) => {
    console.log(err, 'err--pall1')
})


/**
 * promise.race()的结果就是数组元素中先返回的promise实例的结果，
 * 如果先返回的promise实例状态是reject，那么promise.race()的状态就是reject
 * promise.race()应用场景:取消某个异步请求
 * (比如：用户在下载文件时，文件很大，下载要等很久，此时用户点击取消下载按钮，应该终止当前异步的请求)
*/
const pAll2 = Promise.race([p4(), p1()])
pAll2.then(res => {
    console.log(res, 'race')
}).catch((err) => {
    console.log(err, 'race')
})




let isCancel = false
const cancel = () => {
    return new Promise((resolve, reject) => {
        reject('取消请求')
    })
}
const downLoadFile = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('下载成功')
        }, 10000)
    })
}
// const data = Promise([downLoadFile(), cancel()])




